package de.bazinga.rotw.person;

import java.util.Random;

import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.Controller;
import com.jmex.model.animation.JointController;

public class PersonAnimation {

	/**
	 * The Person
	 */
	protected Person person = null;
	
	
	/**
	 * This controller controls the animation of the player
	 */
	protected JointController controller = null;
	
	
	
	/**
	 * Swimm-Rotation
	 */
	private Quaternion swimRot = null;

	protected boolean ducking = false,
		walk = false,
		sneakWalking = false,
		jumping = false,
		standing = false,
		fallingDead = false,
		fireAnim = false,
		swimming = false;
	
	public PersonAnimation(Person person, JointController controller) {
		this.person = person;
		this.controller = controller;
		reset();
		
		
		swimRot = new Quaternion();
		swimRot.fromAngleAxis(FastMath.DEG_TO_RAD * 90, Vector3f.UNIT_X);
	}
	
	
	public void reset() {
		standing = fireAnim = ducking = jumping = walk = sneakWalking = fallingDead = swimming = false;
	}
	
	public JointController getController() {
		return controller;
	}
	
	/**
	 * Play Fire-Animation
	 */
	public void fireAnimation() {
		if(swimming || ducking) return ;
		
		// Fireing is above all! (except swimming and ducking)
		standing = ducking = jumping = walk = sneakWalking = fallingDead = false;
		
		controller.setTimes(63,63 );
        controller.setActive(true);
        fireAnim = true;
	}

	
	/**
	 * Is the Player firing right now?
	 * @return
	 */
	public boolean isFiring() {
		return fireAnim;
	}
	
	
	/**
	 * Play the Duck-Animation
	 */
	public void duck() {
		if(swimming) return ;
		
		controller.setTimes(87,87 );
        controller.setActive(true);
        ducking = true;
	}
	
	/**
	 * Is The player ducking
	 * @return true if he is currently ducking
	 */
	public boolean isDucking() {
		return ducking;
	}
	
	
	
	/**
	 * Play the Walking-Animation
	 */
	public void walk() {
		if(!swimming && !walk && !isDucking() && !isJumping()) {
			controller.setRepeatType(Controller.RT_CYCLE);
			controller.setTimes(1,14 );
	        controller.setActive(true);
	        walk = true;
	        sneakWalking = false;
	        standing = false;
	        fireAnim = false;
		}
	}
	
	/**
	 * Is the walk-animation playing?
	 * @return
	 */
	public boolean isWalking() {
		return walk;
	}
	
	
	
	// Sneak-Walking
	public void sneakWalking() {
		if(!swimming && !sneakWalking && !isDucking() && !isJumping()) {
			controller.setRepeatType(Controller.RT_CYCLE);
			controller.setTimes(15,30 );
	        controller.setActive(true);
	        sneakWalking = true;
	        walk = false;
	        standing = false;
	        fireAnim = false;
		}
	}
	
	public boolean isSneakWalking() {
		return sneakWalking;
	}
	
	
	
	// STANDING
	public void stand() {
		if(swimming) return ;
		
		if(!isStanding() && !isFiring()) {
			int randomNumber = new Random().nextInt(3);
			if(randomNumber == 0) {
				controller.setTimes(206,250 );
			}else if(randomNumber == 1) {
				controller.setTimes(184, 205);
			}else if(randomNumber == 2) {
				controller.setTimes(251, 300);
			}
	        controller.setActive(true);
		}
		standing = true;
        walk = false;
        sneakWalking = false;
        ducking = false;
        jumping = false;
        fallingDead = false;
	}
	
	public boolean isStanding() {
		return standing;
	}
	
	
	// JUMPING
	public void jump() {
		
		if(!isJumping()) {
			controller.setRepeatType(Controller.RT_CLAMP);
			controller.setTimes(103, 111);
			controller.setActive(true);
			jumping = true;
		}
	}
	
	public void stopJumping() {
		if(jumping) {
			jumping = false;
			stand();
		}
	}
	
	public boolean isJumping() {
		return jumping;
	}
	
	

	
	
	// Falling
	public void fall() {
		if(!fallingDead) {
			controller.setRepeatType(Controller.RT_CLAMP);
			controller.setTimes(166, 173);
			controller.setActive(true);
			fallingDead = true;
		}
	}
	
	
	
	/**
	 * DRIVING
	 */
	public void driving() {
		controller.setRepeatType(Controller.RT_CYCLE);
		controller.setTimes(296, 296);
		controller.setActive(true);
	}
	
	
	
	/**
	 * Swimming
	 */
	public void swimming() {
		controller.setRepeatType(Controller.RT_CYCLE);
		controller.setTimes(159, 165);
		controller.setActive(true);
		swimming = true;
		
		person.getBody().setLocalRotation(swimRot);
		person.updateRenderState();
	}
	
	public void stopSwimming() {
		swimming = false;
		
		person.getBody().setLocalRotation(new Quaternion());
		person.updateRenderState();
	}
	
	public boolean isSwimming() {
		return swimming;
	}
}